package rewardsonline.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;

/**
 * TODO-02: To return a spreadsheet, we need a view to generate it - take 
 * a look at the AccountsExcelView class.
 */
@Configuration
@EnableWebMvc // disables Spring Boot's MVC auto-configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

	/**
	 * Define controllers which only render pages (i.e. nothing added to the 
	 * model)
	 */
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/").setViewName("welcome");
		registry.addViewController("/home").setViewName("welcome");
	}
	
	/**
	 * Serve static resources (JS, CSS, images)
	 */
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/**")
		        .addResourceLocations("/","classpath:/META-INF/","classpath:/web-resources/");
	}
	
	@Override
	public void configureViewResolvers(ViewResolverRegistry registry) {
		// Resolves view names to Tiles definitions
		registry.tiles();
	}
	
	@Bean 
	@Description("Configures Tiles")
	TilesConfigurer tilesConfigurer() {
		TilesConfigurer tilesConfigurer = new TilesConfigurer();
		tilesConfigurer.setDefinitions("/WEB-INF/tiles.xml");
		return tilesConfigurer;
	}
	
	/**
	 * TODO-03: Define an AccountsExcelView instance as a Spring Bean. 
	 * What bean id will you use? If not sure, do the next 
	 * TO DO step and then come back. 
	 */
	
	/**
	 * TODO-04: Add a view resolver that can find a view using its bean-name. 
	 * If you weren't sure what bean id to use in the previous step, consider 
	 * it now. The bean-name must be a logical-view name. Look at AccountsController 
	 * to see what view-name it returns (remember we are going to display a _list_ 
	 * of accounts in the spreadsheet). Use the method configureViewResolvers
	 * for a simpler configuration.
	 */
	
	/**
	 * TODO-05: You now have two view-resolvers, check the order is the correct one. 
	 * Which one should be used first? If you aren't sure, set one up, RESTART THE SERVER, 
	 * and see if it works. If you still only get HTML, you got it backwards! Once 
	 * this is working you should ONLY get the spreadsheet returned, even when you 
	 * click Accounts on the home page. Again, 
	 */
	
	/**
	 * TODO-06: Setup a Content Negotiating View Resolver (CNVR), use the 
	 * configureViewResolvers method for a simpler configuration. By default 
	 * it will use the path extension on the URL, which is what we want. RESTART 
	 * THE SERVER. You should now be able to see the account list in HTML again, 
	 * and generate the spreadsheet when "Show as Excel" is clicked.
	 */
	
	/**
	 * TODO-07: If you click on the "Show as JSON" link you will also get 
	 * an HTML list. If you modify the URL to end in accounts.do, again you still 
	 * get HTML. By default HTML is the default content-type when the suffix is 
	 * not recognized because the Accept header defaults to text/html.
	 */
	
	/**
	 * TODO-08: To change this, do the following:
	 * 		a. Setup a ContentNegotiationManager by uncommenting the code below.
	 * 			Note the ignoreAcceptHeader property is enabled, we have explicitly
	 * 			defined HTML as the default format and  and we have told it that we 
	 * 			only generate html, json and xls.
	 * 		b. Inject the manager into the CNVR.
	 * 		c. Set the CNVR's useNotAcceptableStatusCode to true.
	 * 		d. Restart the server.
	 * Everything should work properly but if you click on the :Show as JSON" link
	 * you should get a 406 error because the URL is not recognized.
	 */
	
//	@Override
//    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//		configurer.ignoreAcceptHeader(true);
//		configurer.defaultContentType(MediaType.TEXT_HTML);
//		
//		// These are not strictly necessary, but were needed during the lab to 
//		// demonstrate the 406 error
//		configurer.mediaType("html", MediaType.TEXT_HTML);
//        configurer.mediaType("json", MediaType.APPLICATION_JSON);
//        configurer.mediaType("xls", new MediaType("application", "vnd.ms-excel"));
//    }
	
	/**
	 * TODO-09a: This configuration is very precise. Click on the "Show as 
	 * JSON" link again and then manually change the URL to end in .xxx instead 
	 * of .json. Hit enter and you will get HTML again - xxx is not a recognized 
	 * suffix, so it defaults to HTML. You only get a 406 if you have explicitly 
	 * told it a mediaType to generate but no view exists to generate that type.
	 */
	
	/**
	 * TODO-09b Try commenting out the defaultContentType on configureContentNegotiation and 
	 * restarting the server. If you click on the Accounts link it will popup the 
	 * spreadsheet. No default format is configured so it falls back on the first 
	 * matching view - the Excel view. If you click on the Accounts.html link you 
	 * do get HTML because of the .html suffix in the URL.
	 */
	
	/**
	 * TODO-09c: Restore the defaultContentType on configureContentNegotiation. Comment out 
	 * the mediaTypes property. Restart the server, everything should still work, 
	 * but if you click on the "Show as JSON" link you no longer get a 406 error 
	 * because it doesn't recognize json as a format - it simply defaults to HTML 
	 * instead. Restore the mediaTypes property
	 */
	
	/**
	 * TODO-10: Optional Bonus 1: A JsonViewResolver has been written for 
	 * you. Add it to the chain of view-resolvers in the configureViewResolvers method.
	 */
	
	/**
	 * TODO-11: Optional Bonus 2: Click on a "Show as Json" and you will get 
	 * an error because Jackson doesn't know how to convert an Account to JSON. 
	 * You need to annotate the Percentage class to tell Jackson how to use it. 
	 * Look in Percentage.java for the TO DO step. Restart the server and try clicking 
	 * on a "Show as Json" link and now it should work.
	 */
	
}
